package com.example.usercenter.sys.web;

import com.alibaba.fastjson.JSONObject;
import com.example.usercenter.common.base.Page;
import com.example.usercenter.common.base.ResponseData;
import com.example.usercenter.sys.entity.*;
import com.example.usercenter.sys.service.OrgService;
import com.example.usercenter.sys.service.UserGroupService;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;

import com.example.usercenter.common.base.BaseRestController;
import com.example.usercenter.common.base.BaseService;
import com.example.usercenter.sys.service.UserService;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value="/user")
public class UserController extends BaseRestController<User, Long> {
    @Autowired
    private UserService userService;
    @Autowired
    private UserGroupService userGroupService;
    @Autowired
    private OrgService orgService;

    protected BaseService<User, Long> getService(){
            return userService;
    }

    @RequestMapping(value="/info")
    public ResponseData getUserInfo(HttpServletRequest request, HttpServletResponse response){
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        User user = userService.getByUsername(auth.getName());
        //获取用户当前登录权限
        List<String> roles = auth.getAuthorities().stream().map(item -> {return item.getAuthority();}).collect(Collectors.toList());
        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("roles", roles);
        resultMap.put("user", user);
        return ResponseData.ok("获取用户信息成功", resultMap);
    }

    @PreAuthorize("hasAuthority('USER')")
    @Override
    public ResponseData save(@RequestBody User entity) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        User user = (User) auth.getPrincipal();
        List<Org> orgs = orgService.getOrgsByUser(user, "USER");
        List<Long> orgIds = orgs.stream().map(org -> org.getId()).collect(Collectors.toList());
        if(entity.getOrgUsers() == null || entity.getOrgUsers().size()>0){
            return ResponseData.fail("请先选中用户组织");
        }
        for(OrgUser ou : entity.getOrgUsers()){
            if(!orgIds.contains(ou.getOrgId())){
                return ResponseData.fail("无权限对["+ou.getOrgName()+"]添加用户");
            }
        }
        entity.setPassword(new BCryptPasswordEncoder().encode(entity.getPassword()));
        return super.save(entity);
    }

    @PreAuthorize("hasAuthority('USER')")
    @Override
    public ResponseData get(@PathVariable("id") Long id) {
        return super.get(id);
    }

    @PreAuthorize("hasAuthority('USER')")
    @Override
    public ResponseData update(@RequestBody User entity) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        User user = (User) auth.getPrincipal();
        List<Org> orgs = orgService.getOrgsByUser(user, "USER");
        List<Long> orgIds = orgs.stream().map(org -> org.getId()).collect(Collectors.toList());
        User oldUser = userService.get(entity.getId());
        //获取当前用户无权限操作的用户组织
        List<OrgUser> exclude = new ArrayList<OrgUser>();
        for(OrgUser ou : oldUser.getOrgUsers()){
            if(!orgIds.contains(ou.getOrgId())){
                exclude.add(ou);
            }
        }
        if(exclude.size()>0){
            //排除当前用户无权限操作的用户组织
            Iterator<OrgUser> it = entity.getOrgUsers().iterator();
            while (it.hasNext()){
                OrgUser ou = it.next();
                for(OrgUser ex : exclude){
                    if(ou.getOrgId() == ex.getOrgId()){
                        it.remove();
                        break;
                    }
                }
            }
            //添加当前用户无权限操作的原用户组织
            entity.getOrgUsers().addAll(exclude);
        }
        return super.update(entity);
    }

    @PreAuthorize("hasAuthority('USER')")
    @Override
    public ResponseData delete(@PathVariable("id") Long id) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        User user = (User) auth.getPrincipal();
        if(user.getId() == id){
            return ResponseData.fail("不能删除自身用户");
        }
        List<Org> orgs = orgService.getOrgsByUser(user, "USER");
        List<Long> orgIds = orgs.stream().map(org -> org.getId()).collect(Collectors.toList());
        User delUser = userService.get(id);
        for(OrgUser ou : delUser.getOrgUsers()){
            if(!orgIds.contains(ou.getOrgId())){
                return ResponseData.fail("无权限删除["+ou.getOrgName()+"]下的用户");
            }
        }
        return super.delete(id);
    }

    @PreAuthorize("hasAuthority('USER')")
    @PostMapping(value="/resetPassword")
    public ResponseData resetPassword(@RequestBody User entity){
        long id = entity.getId();
        String password = entity.getPassword();
        entity = new User(id);
        entity.setPassword(new BCryptPasswordEncoder().encode(password));
        if(userService.sensitiveUpdate(entity)){
            return ResponseData.ok("重置密码成功");
        }
        return ResponseData.fail("重置密码失败");
    }

    @PreAuthorize("hasAuthority('USER')")
    @Override
    public ResponseData page(@RequestBody JSONObject params) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        User user = (User) auth.getPrincipal();
        List<Org> orgs = orgService.getOrgsByUser(user, "USER");
        if(orgs.size()==0){
            return ResponseData.fail("查询用户列表时，搜索用户可查看组织范围为空，查询用户列表失败");
        }
        //获取组织ID
        List<Long> orgIds = orgs.stream().map(org -> org.getId()).collect(Collectors.toList());
        params.put("orgIds", orgIds);
        return super.page(params);
    }

    @PreAuthorize("hasAuthority('USER')")
    @Override
    public ResponseData query(@RequestBody JSONObject params) {
        return super.query(params);
    }

    @PreAuthorize("hasAuthority('USER')")
    @Override
    public ResponseData exists(@RequestBody JSONObject params) {
        return super.exists(params);
    }
}